/* $Id: JDatabaseTreePane.java 35 2009-05-06 19:05:18Z aaron.day $ */
package org.crazydays.gameplan.db.swing;


import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import org.crazydays.gameplan.Controller;
import org.crazydays.gameplan.db.Database;
import org.crazydays.gameplan.map.IGameMap;
import org.crazydays.gameplan.model.IDatabaseObserver;
import org.crazydays.gameplan.model.IGameMapObserver;

/**
 * JDatabaseTreePane
 */
public class JDatabaseTreePane
    extends JScrollPane
    implements IDatabaseObserver, IGameMapObserver
{
    /** serial version uid */
    public final static long serialVersionUID =
        "$Id: JDatabaseTreePane.java 35 2009-05-06 19:05:18Z aaron.day $"
            .hashCode();

    /** controller */
    protected Controller controller;

    /**
     * JDatabaseTreePane constructor.
     * 
     * @param controller Controller
     */
    public JDatabaseTreePane(Controller controller)
    {
        this.controller = controller;
    }

    /** tree */
    protected JTree tree;

    /** root */
    protected DatabaseNode root;

    /** maps */
    protected MapsNode maps;

    /** model */
    protected DefaultTreeModel model;

    /**
     * JDatabaseTreePanel constructor.
     * 
     * @param database Database
     */
    public JDatabaseTreePane()
    {
        super(VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
    }

    /**
     * Database opened.
     * 
     * @param database Database
     * @see IDatabaseObserver#opened(Database)
     */
    @Override
    public void opened(Database database)
    {
        loadRoot(database);
        loadMaps(database);

        setViewportView(tree);
    }

    /**
     * Load root node.
     * 
     * @param database Database
     */
    protected void loadRoot(Database database)
    {
        root = new DatabaseNode(database);
        model = new DefaultTreeModel(root);

        tree = new JTree(model);
        tree.addMouseListener(new DatabaseTreeMouseListener(controller, tree));
        tree.setCellRenderer(new DatabaseTreeCellRenderer());

        // tree.addTreeSelectionListener(new DatabaseTreeSelectionListener(
        // controller));
        tree.getSelectionModel().setSelectionMode(
            TreeSelectionModel.SINGLE_TREE_SELECTION);
    }

    /**
     * Load all maps from the database.
     * 
     * @param database Database
     */
    protected void loadMaps(Database database)
    {
        maps = new MapsNode();
        root.add(maps);

        for (IGameMap gameMap : database.getGameMaps()) {
            added(gameMap);
        }

        tree.makeVisible(new TreePath(maps.getPath()));
        model.nodeStructureChanged(root);
    }

    /**
     * Database closed.
     * 
     * @param database Database
     * @see IDatabaseObserver#closed(Database)
     */
    @Override
    public void closed(Database database)
    {
        setViewportView(new JPanel());

        tree = null;
        model = null;
        root = null;
    }

    /**
     * Game map added.
     * 
     * @param gameMap GameMap
     * @see IGameMapObserver#added(IGameMap)
     */
    @Override
    public void added(IGameMap gameMap)
    {
        MapNode node = new MapNode(gameMap);

        maps.add(node);

        tree.makeVisible(new TreePath(node.getPath()));
        model.nodeStructureChanged(maps);
    }

    /**
     * Game map removed.
     * 
     * @param gameMap GameMap
     * @see IGameMapObserver#removed(IGameMap)
     */
    @Override
    public void removed(IGameMap gameMap)
    {
        for (int i = 0; i < maps.getChildCount(); i++) {
            MapNode node = (MapNode) maps.getChildAt(i);

            if (gameMap.getName().equals(node.getUserObject())) {
                maps.remove(i);
                break;
            }
        }
    }
}
